Skip to content

fix(control-plane): withhold auxiliary polls on replan-bound turns - #5287

Merged
huangruiteng merged 5 commits into
mainfrom
codex/aux-monitor-replan-receipt-20260929
Sep 30, 2026
Merged

huangruiteng merged 5 commits into
mainfrom
codex/aux-monitor-replan-receipt-20260929

Conversation

@huangruiteng

Copy link
Copy Markdown
Collaborator

Goal And Delivered Outcome

  • Outcome basis: reproduced auxiliary monitor admission defect in the Codex App heartbeat contract.
  • When a Turn is already bound to autonomous replan, a due auxiliary monitor was advertised as ready, but running its projected command failed with heartbeat_receipt_identity_conflict. The CLI now reports receipt_binding_required, with the valid next step, and omits the unusable command. Todo-bound Turns keep their auxiliary poll command.
  • Intended base: main. Related fix: fence scoped auxiliary Monitor admission and routing #5279 changes the same projection file for scoped User-gate admission; this PR handles the distinct autonomous-replan receipt binding case.

Scope And Continuation

  • Complete within this defect's scope. The change reads the existing TypeScript-owned replan settlement binding; it does not create another receipt authority or change monitor persistence. The adjacent helper remains the appropriate owner, so no broader refactor is needed.

Validation

  • Tested revision: ba04dd2
  • Run state: finished
  • Input classes: synthetic, public_fixture
Check kind Result Public-safe evidence / limitation
unit passed 94 tests across auxiliary availability, work-lane routing, settlement, and monitor observation. Replan-bound, Todo-bound, and unbound projections are asserted.
real_entrypoint passed Three synthetic CLI cases exercise Todo-bound auxiliary polling, due-monitor selection, and replan receipt replay/conflict.
static passed Ruff, Python compilation, git diff --check, and loopx check on both changed paths; no public-boundary findings. loopx check reported two unrelated existing Goal-state warnings.
integration passed loopx canary premerge --from-git-diff with the managed quality gate on the exact commit: 5 direct checks and 18 selected checks passed. Initial setup-only failure (missing npm TypeScript dependency) resolved by npm ci --ignore-scripts before the successful rerun.
  • Coverage and gaps: The public CLI cases cover the existing legal and conflict paths; the focused projection test covers the previously missing replan-bound decision. The exact-scope change-quality gate passed. No frontend entry point changed; this is an agent-facing CLI response.

Frontend / Visual Evidence

  • UI impact: none.

Type of Change

  • Bug fix
  • Test update

LoopX Area

  • Control plane (goals, todos, quota, scheduler, registry, runtime)

Technical Direction

  • Core control-plane hardening: keep the advertised CLI action consistent with the Turn's settlement identity.

Shared-authority RFC fixture impact

N/A. This PR does not claim provider migration or shared authority promotion.

Boundary Checklist

  • Neither the diff nor this PR body discloses private state, credentials, raw traces, internal links, or local machine paths.
  • No maintainer-owned benchmark work was duplicated.
  • The change is scoped to the reproduced monitor admission defect.
  • UI impact is none.
  • Every commit includes a DCO sign-off trailer.

Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
@mergify

mergify Bot commented Sep 29, 2026

Copy link
Copy Markdown

This pull request has merge conflicts with main and cannot be merged
until they are resolved. Please rebase or merge the base branch, @huangruiteng.

Choose the remote for the base repository, not an out-of-date fork.
For a fork clone, first inspect git remote -v; upstream must point
to https://github.com/loopx-project/loopx.git. If it is absent, add it
with git remote add upstream https://github.com/loopx-project/loopx.git.
Then run:

git fetch upstream
git rebase upstream/main
# Resolve each conflict, git add the resolved files, then git rebase --continue.
git push --force-with-lease origin HEAD

For a same-repository clone whose origin points to
https://github.com/loopx-project/loopx.git, use origin instead of
upstream for fetch/rebase. If you prefer merging the base, use
git merge <base-remote>/main and push normally.

Keep the DCO Signed-off-by trailer on every commit when you rebase.
https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork

@mergify mergify Bot added the needs-rebase Mergify: the pull request has merge conflicts with its base branch label Sep 29, 2026

@huangruiteng huangruiteng left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approval conclusion (author-owned PR; GitHub blocks formal self-approval)

评审 head:ba04dd27d967c5f6d34b0e057f23fe690178a4f7。结论:APPROVE,未发现该 head 的阻断项。以下按 LoopX PR review capability 的当前评审契约执行;批准代码结论不等于批准合并。

动机

这个修复解决的是一条不可执行的恢复路径:Turn 已经绑定自主 replan 的结算身份,却仍向 Agent 展示辅助 monitor-poll 命令。真正执行时,原有 admission 会拒绝把同一 Turn 改绑为 Todo 观察,造成“状态说可以执行、实际执行被拒绝”的反复尝试。目标不是放宽单一结算身份,而是让 CLI 投影准确呈现这个边界。它完成了这个有用且独立的修复,不声称关闭整个长期运行路线图。

改动思路

入口仍是 quota should-run 生成的 interaction contract。原来的类型化 replan settlement owner 已经决定绑定究竟是 Todo 还是自主 replan;本 PR 读取其结果,不从 Todo 文案、任务类别或监控列表另造判断源。只在自主 replan 分支撤下两条不可执行命令,保留 monitor 上下文和“先结算、再从 Todo-bound Turn 观察”的恢复提示。已有显式未绑定与缺少 Turn ID 的拒绝优先级不变,Todo-bound replan 仍可执行辅助 poll。

正向恢复也做了真实验证:完成 replan 的 refresh-state 和 spend-slot 后,新建/认领的验证 Todo 可以成为后续 Turn 的绑定;该 Turn 执行 monitor-poll 成功。新 Turn 首次投影若要求显式绑定,就使用选中 Todo 的 ID 补充绑定;没有绕过原有授权或结算检查。

具体改动

生产文件增加 16 行,测试增加 55 行、删除 2 行;没有增加持久化状态、CLI 参数或第二个结算 owner。

关键代码讲解

  1. _turn_scoped_cli_settlement_context(interaction_contract.py:547)取得已经验证的 replan settlement contract,并与当前 Turn 的结算计划一起返回。它是本次判断的输入来源,选中 Todo 时继续返回 Todo 绑定,而不是仅凭存在 replan obligation 就阻断。
  2. projectReplanSettlementContract(replan_settlement.ts:174,未修改)保持类型化绑定联合的所有权。Python 只消费其 settlement_binding.kind;这次没有复制 TypeScript 的状态机,也没有改变 lease、claim 或额度权限。
  3. _build_interaction_cli_channel(interaction_contract.py:1265)在原有显式绑定检查、缺失 Turn ID 检查之后,新增自主 replan 的命令可用性分支。它输出 receipt_binding_required 和可操作的下一步,且同时省略普通与 material-change 命令;其他路径继续由原有 builder 输出。辅助 poll 仍是可选、不抢占主任务、no-spend,并不取消主工作义务。

测试文件覆盖自主 replan 被撤下命令、Todo-bound replan 保留命令和普通未绑定非-replan 路径的原有投影。这里的普通未绑定投影兼容性不等于真实 admission 被放宽,最终仍由 receipt admission 拒绝不合法身份。

对主干的风险

最危险的反向回归是把所有 replan 都禁掉,使合法 Todo-bound replan 的观察永久停住。本次按类型化绑定区分,不按 replan 这个词或任务文案分类。独立的 base/head 合成 fixture 通过真实 CLI 和原有 native admission 验证:基线错误显示 ready,执行得到身份冲突;head 正确显示绑定前置条件,强行执行旧命令仍被拒绝,状态字节不变、观察记录为零、花费为零。随后恢复到新的 Todo-bound Turn,poll 成功;普通 Todo-bound poll 重放仅保留一条观察,且不花额度。四组完整投影对照还保留了既有拒绝优先级和合法路径。

本地验证:7 个相关测试文件共 66 个测试通过;loopx canary premerge --from-git-diff --git-diff-base ee1ea64b0aef45fdda81d2d7e48da356a1750eab 的 5 项直接检查与 18 项选中检查通过;两个修改文件 Ruff 与 diff whitespace 检查通过。真实边界是隔离的 File/SQLite 合成状态及 native admission,不涉及活跃 Goal、真实外部监控请求或付费模型。独立恢复 fixture 的指纹为 c3a83b79e5a8e35637536979c48cea4ee8da8f4b6c8951c6cd129eb84f9e0032,base 为上述不可变提交,head 为本次评审提交。

语义与 CI 对齐

本 PR 复用已有绑定语义,显式披露“原先展示不可执行命令,现在展示结算前置条件”的默认行为变化;错误提示使用目标无关的 Turn、Todo、replan 术语,没有把强制工作义务称作建议。它不是新增 opt-in 能力,因此没有新增默认关闭门或自动安装指令。当前 Goal 的评审策略不等待远端 CI,本次未查询或轮询 CI。

最新 main 已含 #5279 的同文件 scoped-gate 修复,这与本 PR 的 replan 投影问题不是同一修复。已有合并冲突须整合后再验证新 head,不能直接继承本次批准;这属于合并就绪条件,不是该不可变 head 的代码阻断发现。

我的整体评价

long_horizon:improved,避免反复尝试不可能的辅助命令,并证明结算后仍能继续有用工作。user_experience:improved,CLI 从误导性的 ready 变为准确前置条件,恢复只补充已有权威状态所需的绑定,没有新增用户确认。代码量与问题相称,兼容路径保持原有语义;未来向前的精简检查考虑了单一绑定 owner,当前已经复用它,无需为了 16 行投影增加新抽象。残余风险是与最新 main 整合后的 exact-head 验证,以及真实外部监控自身的可用性;后者不在此修复的验收范围。本轮不合并。

English verdict: APPROVE - ba04dd2. Auxiliary commands now match the existing single-Turn receipt boundary; actual CLI refusal, settlement-to-Todo recovery and replay were verified. 66 focused tests and all selected premerge checks passed. Rebase/integration requires a fresh exact-head review; no merge or remote CI polling.

cocolord
cocolord previously approved these changes Sep 30, 2026

@cocolord cocolord left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

动机

这个 PR 修复的是一条可复现的控制面自相矛盾:同一 Turn 的 heartbeat receipt 已经绑定到 autonomous replan,但状态变化后出现一个到期的 watch-only Monitor 时,旧版 quota should-run 仍把辅助 monitor-poll 投影为 ready;照着命令执行却必然得到 heartbeat_receipt_identity_conflict。这会让自动化反复尝试一个不可能成功的动作。目标是让投影诚实反映既有的单 Turn 单结算身份约束,而不是放宽 Monitor 写入权限。

改动思路

实现复用既有 TypeScript replan settlement owner 的类型化结果。Python 的 interaction contract 只读取 replan_settlement_contract.settlement_binding.kind:显式未绑定和缺少 Turn ID 的既有拒绝优先级保持不变;绑定种类为 autonomous_replan 时,辅助观察改为 receipt_binding_required,给出先结算当前 replan、再从 Todo-bound Turn 观察的恢复路径,并撤下普通及 material-change 两条不可执行命令。Todo-bound replan 继续走原来的 ready 分支,真实 poll、回执和零额度语义不变。

具体改动

完整 diff 只有两个文件、+71/-2,没有新持久化字段、CLI 参数、权限或第二状态权威。

关键代码讲解

  • _turn_scoped_cli_settlement_context 继续负责把 TypeScript owner 产生的 settlement plan 与 replan settlement contract 带入 CLI 投影;它没有在 Python 重新判断 replan 状态。
  • projectReplanSettlementContract 是未修改的类型化决策 owner,依据是否有 selected Todo 生成 todo 或 autonomous_replan 的 discriminated binding。本 PR 消费这个字段,而非按 Todo 文案、标题或子串分类。
  • _build_interaction_cli_channel 在辅助 Monitor 分支读取 settlement_binding。仅当 kind 为 autonomous_replan 时返回 auxiliary_monitor_replan_receipt_binding 并省略命令;Todo 绑定和普通合法 Turn 仍生成原命令。
  • test_auxiliary_monitor_poll_availability.py 增加 replan-bound 反例及 Todo-bound replan 正例,并补齐 Codex App heartbeat execution context,使断言覆盖真实命令投影形状。

对主干的风险

主要风险是条件过宽,导致任何带 replan obligation 的 Turn 都失去合法辅助观察。独立 public CLI 反事实排除了这一点:在 immutable base 上,先建立 autonomous-replan receipt、再出现 advancement Todo 与到期 Monitor 时,投影为 ready 且含两条命令,但强制执行返回 heartbeat_receipt_identity_conflict,没有写入观察;在 exact head 上,同一输入变为 receipt_binding_required,两条命令均被移除,强制旧命令仍失败关闭。另一条 Todo-bound replan 路径仍投影 ready,真实 poll 成功、只写入一条 observation,quota spend 为 0。42 个相关测试、changed-file Ruff、Python compile 和 diff whitespace 检查通过。

远端 4 个失败检查也已用同一命令在 immutable base ee1ea64b0aef45fdda81d2d7e48da356a1750eab 与 exact head 上复现:两项 registry census 都报告同一个 loopx/cli.py metadata drift,两项 settlement 测试都保持相同的 scheduler ACK 断言形状;这些路径不在本 PR diff,因此不归因于本改动。当前 head 与最新 main 存在 interaction_contract.py 内容冲突,因为 #5279 已改动同一分支。它不否定该 immutable head 的行为结论,但 rebase/整合后的新 head 必须重新跑上述反事实与 freshness review,当前批准不构成 merge-ready。

语义与 CI 对齐

改动复用现有 todo | autonomous_replan typed binding,没有 substring denylist;提示使用 Turn、Todo、replan 等通用控制面术语。行为变化已明确为“从展示必失败命令改为展示机器前置条件”,receipt_binding_required 是强制 admission 约束而不是建议。现有 required CI 仍红且 PR 仍有冲突,所以合并门禁保持关闭。

我的整体评价

APPROVE exact head ba04dd27d967c5f6d34b0e057f23fe690178a4f7。收益已经由 base/head 真实 CLI 差分验证:错误的 ready 被准确的 binding requirement 取代,非法写入继续失败关闭,Todo-bound 合法观察不被误伤且不消费额度。代码量小、职责落在现有投影边界、没有复制状态机,也没有未闭合的 exact-head 行为风险。相关的 bounded future-facing 检查认为无需再加抽象;真正剩余的是与 #5279 的整合工作,作者更新 head 后必须重新审查。此批准仅是代码评审结论,不授予合并权限。

English verdict: APPROVE ba04dd27d967c5f6d34b0e057f23fe690178a4f7. A real base/head CLI counterfactual confirms that the misleading ready command is removed only for autonomous-replan-bound Turns, while Todo-bound replan polling still succeeds with one observation and zero spend. Focused tests and static checks pass; four CI failures match the immutable base. The branch conflicts with current main, so any rebased head requires a fresh review and this approval is not merge authority.

Signed-off-by: huangruiteng <huangrt01@163.com>
Signed-off-by: huangruiteng <huangrt01@163.com>
Signed-off-by: huangruiteng <huangrt01@163.com>
…lan-receipt-20260929

Signed-off-by: huangruiteng <huangrt01@163.com>

@huangruiteng huangruiteng left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approval conclusion (author-owned PR; GitHub blocks formal self-approval)

Exact reviewed head: c7ee1c28f61b22eb7544321e83da5b65fdf12d1a; integrated base: 0644abaaa95cb14573ff342830d1838065c98143.

动机

评审整个 PR 及与当前主干的组合。问题是 autonomous-replan-only Turn 给出了看似可执行的辅助 monitor 命令,但它无法绑定到当前结算身份;执行后才报 identity conflict,浪费回合且仍需操作者补位。正确结果是入口就说明缺什么绑定,并保留结算后通过 Todo-bound Turn 继续观测的真实路径。

改动思路

最小方案是让现有 interaction projection 消费已有 typed replan_settlement_contract.settlement_binding,不另建排程、配额或 receipt 决策 owner。Python 仍是展示/CLI transport,既有 TypeScript settlement 与 native quota/lease 合法性保持权威。禁止所有 replan monitor 会过度拦截,所以只针对 kind=autonomous_replan;已有选定 Todo 的重规划仍保持可执行。

具体改动

关键代码讲解

interaction_contract 在显式 receipt-binding 和缺少 turn_instance_id 两项拒绝之后、原 user-gate scope 检查之前识别 autonomous-replan binding,给出 receipt_binding_required 和恢复说明,同时不发普通/物质变化 poll 命令。整合冲突时保留主干 gate_scope 独立性约束及 target-key 参数,没有覆盖它们。availability 测试加入 replan-only 拒绝和 todo-bound replan 正例,仍验证普通合法 Turn 和显式身份拒绝优先级。

相邻 state-machine smoke 原先要求 transport 自动 trim required-read 命令,但主干的 admitted-command 契约明确要求原样运输;不可变 main/head 都复现该断言失败。本次将 oracle 修为输入命令完整镜像到 agent/CLI 两端,user 端仍不显示,而非修改生产 transport 或删掉检查。

对主干的风险

语义与 CI 对齐

风险集中于过度封锁独立 monitor、错误判定 settlement kind 和丢失主干用户 gate。当前精确范围的 25 项 availability/routing/settlement/CLI projection 回归、35 项真实 native/public-CLI/lease monitor 回归及共享 state-machine smoke 通过。相同 admitted replan-only fixture 在 main 是 ready+两条命令,在 head 是 binding-required+零命令;选定 Todo 的 replan 仍可执行。native 正负验证包含身份/租约/重试、结算后继续与零重复业务效果。没有绕过活跃 Goal、重写历史 receipt 或把有记录的 blocker 误称恢复成功。

最终 premerge 全通过,质量回执绑定当前三文件范围;无失败、必需跳过或 manual hold。早期旧 whitespace oracle 的失败保留并通过 base/head 归因后修复。公开边界及 DCO 合格;按 Goal policy 未查询或等待 CI。此处 CLI transport 变化不要求前端配置 companion,既有 App/Lark 共用同一 interaction/status 合法性;没有新开关或状态 owner。

我的整体评价

APPROVE:拒绝范围有精确 typed 依据,合法独立 monitor 和 Todo-bound replan 继续路径保留。相邻修正没有扩散到权限或排程规则。按所有者明确授权合并当前提交;该修复只闭合错误命令投影与恢复路径,不宣称全局自主协作已经验收。

No blocking finding. Residual risk: browser provider fixtures do not certify model intent quality; installed readback follows merge.

English verdict: APPROVE - exact head c7ee1c28f61b22eb7544321e83da5b65fdf12d1a; integration blockers resolved and affected native/packaged invariants plus risk-based premerge pass. Owner-authorized merge; broader adoption and installed delivery are separate readbacks.

@huangruiteng
huangruiteng merged commit 21f89e4 into main Sep 30, 2026
7 checks passed
@huangruiteng
huangruiteng deleted the codex/aux-monitor-replan-receipt-20260929 branch September 30, 2026 10:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-rebase Mergify: the pull request has merge conflicts with its base branch

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants